package parser;

import java.util.ArrayList;
import java.util.HashMap;
import prjClasses.Error;
import prjClasses.*;



public class RequestParser {
	private final String game = "game";
	private final String player = "player";
	private final String discipline = "discipline";
	private final String group = "group";
	private final String league = "league";
	private final String rating = "rating";
	private final String team = "team";
	private final String touranment = "tournament";
	private final String user = "user";
	private final String error = "error";
	private final String serviceResponce = "serviceResponce";

	private final String type = "type";
	private final String id = "id";
	private final String tournament_id = "tournament_id";
	private final String player_id = "player_id";
	private final String owner = "owner";
	private final String status = "status";
	private final String group_id = "group_id";
	private final String login = "login";
	private final String password = "password";
	private final String firstname = "firstname";
	private final String lastname = "lastname";
	private final String age = "age";
	private final String city = "city";
	private final String info = "info";
	private final String e_mail = "e_mail";
	private final String contact_information = "contact_information";
	private final String link_of_source = "link_of_source";
	private final String description = "description";
	private final String rating_id = "rating_id";
	private final String discipline_id = "discipline_id";
	private final String name = "name";
	private final String rules = "rules";
	private final String league_id = "league_id";
	private final String victory = "victory";
	private final String lose_out = "lose_out";
	private final String draw = "draw";
	private final String achivements = "achivements";
	private final String scope = "scope";
	private final String count_players = "count_players";
	private final String date_of_inception = "date_of_inception";
	private final String date_of_end = "date_of_end";
	private final String group_stage = "group_stage";
	private final String final_stage = "final_stage";
	private final String prize = "prize";
	private final String errorHappend = "errorHappend";
	private final String errorId = "errorId";
	private final String operationFinished = "operationFinished";
	private final String message = "message";
	private final String exceptionOfErrorStr="exceptionOfErrorStr";
	private final String rate="rate";
	private final String number="number";
	private final String objectIdWhereOccurred="objectIdWhereOccurred";
	private final String instanceId = "instanceId";

	public HashMap<String, ArrayList<Object>> parseRequest(String[][] data) {
		ArrayList<HashMap<String, ArrayList<String>>> allDataObj = ParserToMap
				.parse(data);
		HashMap<String, ArrayList<Object>> result = new HashMap<String, ArrayList<Object>>();

		for (int i = 0; i < allDataObj.size(); i++) {
			Object object = getObjectByMap(allDataObj.get(i));
			String typeObj = arrToStr(allDataObj.get(i).get(type));
			result = addToArr(result, object, typeObj);
		}
		return result;
	}

	private HashMap<String, ArrayList<Object>> addToArr(
			HashMap<String, ArrayList<Object>> data, Object objToAdd,
			String typeObj) {

		ArrayList<Object> arrOfObjectOneType = new ArrayList<Object>();
		if (data.get(typeObj) != null)
			arrOfObjectOneType.addAll(data.get(typeObj));
		arrOfObjectOneType.add(objToAdd);
		data.remove(typeObj);
		data.put(typeObj, arrOfObjectOneType);
		return data;
	}

	private Object getObjectByMap(HashMap<String, ArrayList<String>> objMap) {
		Object object = null;
		String typeObj = arrToStr(objMap.get(type));

		if (typeObj.equalsIgnoreCase(game))
			object = parseGame(objMap);
		if (typeObj.equalsIgnoreCase(user))
			object = parseUser(objMap);
		if (typeObj.equalsIgnoreCase(player))
			object = parsePlayer(objMap);
		if (typeObj.equalsIgnoreCase(discipline))
			object = parseDiscipline(objMap);
		if (typeObj.equalsIgnoreCase(group))
			object = parseGroup(objMap);
		if (typeObj.equalsIgnoreCase(league))
			object = parseLeague(objMap);
		if (typeObj.equalsIgnoreCase(rating))
			object = parseRating(objMap);
		if (typeObj.equalsIgnoreCase(team))
			object = parseTeam(objMap);
		if (typeObj.equalsIgnoreCase(touranment))
			object = parseTournament(objMap);
		if (typeObj.equalsIgnoreCase(error))
			object = parseError(objMap);
		if (typeObj.equalsIgnoreCase(serviceResponce))
			object = parseServiceAnswer(objMap);
		
		if (object == null)
			unknownObject(objMap);
		return object;
	}

	private Game parseGame(HashMap<String, ArrayList<String>> dataMap) {
		Game result = new Game();
		result.setGameId(arrToInt(dataMap.get(id)));
		result.setTournamentId(arrToInt(dataMap.get(tournament_id)));
		result.setPlayerId(arrToInt(dataMap.get(player_id)));
		result.setOwner(arrToInt(dataMap.get(owner)));
		result.setStatus(arrToStr(dataMap.get(status)));
		return result;
	}

	private User parseUser(HashMap<String, ArrayList<String>> dataMap) {
		User result = new User();
		result.setUserId(arrToInt(dataMap.get(id)));
		result.setGroupId(arrToInt(dataMap.get(group_id)));
		result.setLogin(arrToStr(dataMap.get(login)));
		result.setPassword(arrToStr(dataMap.get(password)));
		result.setFirstname(arrToStr(dataMap.get(firstname)));
		result.setLastname(arrToStr(dataMap.get(lastname)));
		result.setAge(arrToStr(dataMap.get(age)));
		result.setCity(arrToStr(dataMap.get(city)));
		result.setInfo(arrToStr(dataMap.get(info)));
		result.setE_mail(arrToStr(dataMap.get(e_mail)));
		result.setContactInformation(arrToStr(dataMap.get(contact_information)));
		result.setLinkOnSource(arrToStr(dataMap.get(link_of_source)));
		result.setDescription(arrToStr(dataMap.get(description)));
		return result;
	}

	private Player parsePlayer(HashMap<String, ArrayList<String>> dataMap) {
		Player result = new Player();
		result.setPlayerId(arrToInt(dataMap.get(id)));
		result.setOwner(arrToInt(dataMap.get(owner)));
		result.setRatingId(arrToInt(dataMap.get(rating_id)));
		result.setFirstname(arrToStr(dataMap.get(firstname)));
		result.setLastname(arrToStr(dataMap.get(lastname)));
		return result;
	}

	private Discipline parseDiscipline(
			HashMap<String, ArrayList<String>> dataMap) {
		Discipline result = new Discipline();
		result.setDisciplineId(arrToInt(dataMap.get(id)));
		result.setName(arrToStr(dataMap.get(name)));
		result.setRules(arrToStr(dataMap.get(rules)));
		return result;
	}

	private Group parseGroup(HashMap<String, ArrayList<String>> dataMap) {
		Group result = new Group();
		result.setGroupId(arrToInt(dataMap.get(id)));
		result.setName(arrToStr(dataMap.get(name)));
		return result;
	}

	private League parseLeague(HashMap<String, ArrayList<String>> dataMap) {
		League result = new League();
		result.setLeagueId(arrToInt(dataMap.get(id)));
		result.setDisciplineId(arrToInt(dataMap.get(discipline_id)));
		result.setName(arrToStr(dataMap.get(name)));
		result.setStatus(arrToInt(dataMap.get(status)));
		result.setOwner(arrToInt(dataMap.get(owner)));
		return result;
	}

	private Rating parseRating(HashMap<String, ArrayList<String>> dataMap) {
		Rating result = new Rating();
		result.setRatingId(arrToInt(dataMap.get(id)));
		result.setVictory(arrToInt(dataMap.get(victory)));
		result.setLoseOut(arrToInt(dataMap.get(lose_out)));
		result.setDraw(arrToInt(dataMap.get(draw)));
		result.setAchivements(arrToStr(dataMap.get(achivements)));
		result.setScope(arrToInt(dataMap.get(scope)));
		return result;
	}

	private Team parseTeam(HashMap<String, ArrayList<String>> dataMap) {
		Team result = new Team();
		result.setTeamId(arrToInt(dataMap.get(id)));
		result.setName(arrToStr(dataMap.get(name)));
		result.setRatingId(arrToInt(dataMap.get(rating_id)));
		result.setDisciplineId(arrToInt(dataMap.get(discipline_id)));
		result.setOwner(arrToInt(dataMap.get(owner)));
		result.setCountPlayers(arrToInt(dataMap.get(count_players)));
		return result;
	}

	private Tournament parseTournament(
			HashMap<String, ArrayList<String>> dataMap) {
		Tournament result = new Tournament();
		result.setTouranmentId(arrToInt(dataMap.get(id)));
		result.setLeagueId(arrToInt(dataMap.get(league_id)));
		result.setOwner(arrToInt(dataMap.get(owner)));
		result.setName(arrToStr(dataMap.get(name)));
		result.setDateOfInception(arrToStr(dataMap.get(date_of_inception)));
		result.setDateOfEnd(arrToStr(dataMap.get(date_of_end)));
		result.setStatus(arrToStr(dataMap.get(status)));
		result.setGroupStage(arrToInt(dataMap.get(group_stage)));
		result.setFinalStage(arrToInt(dataMap.get(final_stage)));
		result.setPrize(arrToStr(dataMap.get(prize)));
		return result;
	}

	private ServiceResponse parseServiceAnswer(
			HashMap<String, ArrayList<String>> dataMap) {
		ServiceResponse result = new ServiceResponse();
		result.setserviceResponseId(arrToInt(dataMap.get(id)));
		result.setErrorId(arrToInt(dataMap.get(errorId)));
		result.setEntityId(arrToInt(dataMap.get(instanceId)));
		result.setErrorHappend(arrToBool(dataMap.get(errorHappend)));
		result.setMessage(arrToStr(dataMap.get(message)));
		result.setOperationFinished(arrToBool(dataMap.get(operationFinished)));
		return result;
	}

	private Error parseError(
			HashMap<String, ArrayList<String>> dataMap) {
		Error result=new Error();
		result.setErrorId(arrToInt(dataMap.get(id)));
		result.setDescription(arrToStr(dataMap.get(description)));
		result.setExceptionOfErrorStr(arrToStr(dataMap.get(exceptionOfErrorStr)));
		result.setNumber(arrToInt(dataMap.get(number)));
		result.setObjectIdWhereOccurred(arrToInt(dataMap.get(objectIdWhereOccurred)));
		result.setRate(arrToInt(dataMap.get(rate)));
		return result;
	}
	
	private String arrToStr(ArrayList<String> data) {
		String result = null;
		if (data != null && !data.isEmpty()) {
			result = data.get(0);
		}
		return result;
	}

	private int strToInt(String data) {
		int result = 0;
		if (data != null && !data.equals(""))
			result = Integer.valueOf(data).intValue();
		return result;
	}
	
	private boolean strToBool(String data) {
		boolean result = false;
		if (data != null && !data.equals(""))
			result = Boolean.valueOf(data);
		return result;
	}

	private int arrToInt(ArrayList<String> data) {
		String str = arrToStr(data);
		return strToInt(str);
	}

	private boolean arrToBool(ArrayList<String> data) {
		String str = arrToStr(data);
		return strToBool(str);
	}


	private void unknownObject(HashMap<String, ArrayList<String>> objMap) {
		System.out.println("[!] Detected unknown object!");
		System.out.println("ID of object: " + arrToStr(objMap.get(id)));
	}
}
